﻿using System;
using System.Text;
using System.Web.Mvc;

namespace WebExam.Core.Extensions
{
    public static class PagerHelper
    {
        private const string REQUEST_PAGEINDEX_NAME = "page";
        private const int PAGEER_COUNT = 5;
        private static string formatPager = string.Empty;

        public static string AjaxPager(this HtmlHelper html, int pageSize, int totalCount)
        {
            formatPager = "javascript:to_page({0});";

            return GeneratePager(html, pageSize, totalCount);
        }

        public static string NormalPager(this HtmlHelper html, int pageSize, int totalCount)
        {
            formatPager = "?page={0}";

            return GeneratePager(html, pageSize, totalCount);
        }

        public static string NormalPager(this HtmlHelper html, int pageSize, int totalCount, string otherParams)
        {
            if (!string.IsNullOrEmpty(otherParams))
            {
                formatPager = "?page={0}&" + otherParams + "'";
            }
            else
            {
                formatPager = "?page={0}";
            }

            return GeneratePager(html, pageSize, totalCount);
        }

        private static string GeneratePager(HtmlHelper html, int pageSize, int totalCount)
        {
            var totalPagesCount = Math.Max((totalCount + pageSize - 1) / pageSize, 1);
            if (totalPagesCount <= 1) return string.Empty;

            var currentPageIndex = GetCurrentPage(html, totalPagesCount);

            var output = new StringBuilder();
            output.Append("<ul class=\"page\" >");

            //HandleFirstPage(output, currentPageIndex);
            HandlePreviousPage(output, currentPageIndex);
            HandlePagers(output, totalPagesCount, currentPageIndex);
            HandleNextPage(output, totalPagesCount, currentPageIndex);
            //HandleLastPage(output, totalPagesCount, currentPageIndex);
            output.Append("<div class=\"clear\"> </div>");
            output.Append("</ul>");

            return output.ToString();
        }

        private static void HandlePreviousPage(StringBuilder output, int currentPageIndex)
        {
            if (currentPageIndex == 1)
            {
                output.Append(GetATag("<<", "javascript:void(0)", ""));
            }
            else
            {
                output.Append(GetATag("<<", GetAHref(currentPageIndex - 1), ""));
            }
        }

        private static void HandlePagers(StringBuilder output, int totalPagesCount, int currentPageIndex)
        {
            int startIndex = GetStartIndex(totalPagesCount, currentPageIndex);

            for (var i = 0; i < PAGEER_COUNT; i++)
            {
                int pageIndex = startIndex + i;

                if (pageIndex > totalPagesCount) break;
                if (currentPageIndex == pageIndex)
                {
                    output.Append(GetATag(pageIndex, GetAHref(pageIndex), "pageliclick"));
                }
                else
                {
                    output.Append(GetATag(pageIndex, GetAHref(pageIndex), ""));
                }

            }
        }

        private static void HandleNextPage(StringBuilder output, int totalPagesCount, int currentPageIndex)
        {
            if (currentPageIndex < totalPagesCount) output.Append(GetATag(">>", GetAHref(currentPageIndex + 1), "second_page"));
            else
            {
                output.Append(GetATag(">>", "javascript:void(0)", "second_page"));
            }
        }

        private static int GetCurrentPage(HtmlHelper html, int totalPagesCount)
        {
            var queryString = html.ViewContext.HttpContext.Request.QueryString;
            var currentPageIndex = 1;
            int.TryParse(queryString[REQUEST_PAGEINDEX_NAME], out currentPageIndex);

            if (currentPageIndex <= 0) currentPageIndex = 1;
            if (currentPageIndex > totalPagesCount) currentPageIndex = totalPagesCount;
            return currentPageIndex;
        }

        private static int GetStartIndex(int totalPagesCount, int currentPage)
        {
            var leftEdge = currentPage - PAGEER_COUNT / 2;
            var startIndex = leftEdge <= 0 ? 1 : leftEdge;
            var rightEdge = startIndex - 1 + PAGEER_COUNT;
            if (totalPagesCount >= PAGEER_COUNT && rightEdge > totalPagesCount) startIndex -= rightEdge - totalPagesCount;

            return startIndex;
        }

        private static string GetATag(int pageIndex, string href, string style)
        {
            return string.Format("<li><a class='{2}' href='{0}'>{1}</a></li>", href, pageIndex, style);
        }

        private static string GetATag(string inner, string href, string style)
        {
            return string.Format("<li><a class='{2}' href='{0}'>{1}</a></li>", href, inner, style);
        }

        private static string GetAHref(int pageIndex)
        {
            return string.Format(formatPager, pageIndex);
        }

        public static int GetStartIndex(int? page, int totalCount, int pageSize)
        {
            var start = 0;
            var totalPages = Math.Max((totalCount + pageSize - 1) / pageSize, 1);
            if (page != null)
            {
                var currentPage = page.Value;
                if (currentPage < 1)
                {
                    currentPage = 1;
                }
                if (currentPage > totalPages)
                {
                    currentPage = totalPages;
                }
                start = (currentPage - 1) * pageSize;
            }
            return start;
        }
    }
}